# -*- coding: utf-8 -*-
import json
from functools import wraps
from flask import request, g
from common.response import error
from common.error_code import ErrorCode
from common.log import logger

def validate_request(request_cls):
    """请求参数验证装饰器"""
    def decorator(f):
        @wraps(f)
        def wrapper(*args, **kwargs):
            try:
                # 记录请求日志
                log_request()
                
                # 获取请求数据
                if request.method in ['POST', 'PUT', 'PATCH']:
                    data = request.get_json(silent=True) or {}
                else:
                    data = request.args.to_dict()
                
                # 验证并创建请求对象
                req_obj = request_cls.from_dict(data)
                g.request_data = req_obj
                
                # 执行原函数
                response = f(*args, **kwargs)
                
                # 记录响应日志
                log_response(response)
                
                return response
                
            except ValueError as e:
                logger.warning(f"请求参数错误: {str(e)}")
                return error(ErrorCode.INVALID_PARAM, str(e))
            except Exception as e:
                logger.exception("请求处理异常")
                return error(ErrorCode.INTERNAL_ERROR, "服务器内部错误")
                
        return wrapper
    return decorator

def log_request():
    """记录请求日志"""
    try:
        request_data = request.get_json(silent=True) or request.args.to_dict()
        logger.info(
            f"USER - {g.user_id if hasattr(g, 'user_id') else 'Unknown'},"
            f"REQUEST - method: {request.method}, path: {request.path}, "
            f"params: {json.dumps(request_data, ensure_ascii=False)}"
        )
    except Exception:
        logger.exception("记录请求日志失败")

def log_response(response):
    """记录响应日志"""
    try:
        logger.info(
            f"USER - {g.user_id if hasattr(g, 'user_id') else 'Unknown'},"
            f"RESPONSE - path: {request.path}, "
            f"response: {json.dumps(response.json, ensure_ascii=False)}"
        )
    except Exception:
        logger.exception("记录响应日志失败")

def require_role(roles):
    """
    角色检查装饰器
    :param roles: 允许访问的角色列表，例如 ['admin', 'teacher']
    """
    def decorator(f):
        @wraps(f)
        def wrapper(*args, **kwargs):
            if not hasattr(g, 'role') or g.role not in roles:
                return error(ErrorCode.FORBIDDEN, "没有权限访问该接口")
            return f(*args, **kwargs)
        return wrapper
    return decorator